package com.xcm.util;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.TimeZone;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * 日期工具类
 */
public class DateTools  {

	private static final Log log = LogFactory.getLog(DateTools.class);

	public static final long HOUR_TO_MILLISECOND = 60 * 1000;

	public static final String DAY_LAST_TIME = " 23:59:59";

	public static final String DATE_PATTERN_TIME = "HH:mm:ss";

	public static final String DATE_PATTERN_MONTH = "yyyy-MM";

	public static final String DATE_PATTERN_MONTH_DAY = "MM-dd";

	public static final String DATE_PATTERN_DAY = "yyyy-MM-dd";

	public static final String DATE_PATTERN_NUMBER_DAY = "yyyyMMdd";

	public static final String DATE_PATTERN_NUMBER_DAY_CHINESE = "yyyy年MM月dd日";

	public static final String DATE_PATTERN_NUMBER = "yyyyMMddHHmmss";

	public static final String DATE_PATTERN_DEFAULT = "yyyy-MM-dd HH:mm:ss";

	public static final String DATE_PATTERN_NUMBER_DAY_CHINESE_ALL = "yyyy年MM月dd日HH时mm分ss秒";
	// 十二生肖
	public static final String[] ZODIAC_ARR = { "猴", "鸡", "狗", "猪", "鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊" };
	// 十二星座
	public static final String[] CONSTELLATION_ARR = { "水瓶座", "双鱼座", "白羊座", "金牛座", "双子座", "巨蟹座", "狮子座", "处女座", "天秤座",
			"天蝎座", "射手座", "摩羯座" };
	// 每个星座对应的每月最大日期
	public static final int[] CONSTELLATION_EDGE_DAY = { 20, 19, 21, 21, 21, 22, 23, 23, 23, 23, 22, 22 };

	/**
	 * 获取当前年份
	 */
	public static int getSysYear() {
		Calendar cal = Calendar.getInstance();
		return cal.get(Calendar.YEAR);
	}

	/**
	 * 获取当前月份，Calendar.MONTH是从零开始
	 */
	public static int getSysMonth() {
		Calendar cal = Calendar.getInstance();
		return (cal.get(Calendar.MONTH) + 1);
	}

	/**
	 * 获取当前号数
	 */
	public static int getSysDay() {
		Calendar cal = Calendar.getInstance();
		return cal.get(Calendar.DAY_OF_MONTH);
	}

	/**
	 * 获取当前小时
	 */
	public static int getSysHour() {
		Calendar cal = Calendar.getInstance();
		return cal.get(Calendar.HOUR_OF_DAY);
	}

	/**
	 * 获取当前分钟
	 */
	public static int getSysMinute() {
		Calendar cal = Calendar.getInstance();
		return cal.get(Calendar.MINUTE);
	}

	/**
	 * 时间校验: 开始时间不能大于当前时间.
	 */
	public static Date validateStartDate(Date startDate) {
		Date today = new Date();
		if (startDate.compareTo(today) == 1) {
			startDate = today;
		}
		return startDate;
	}

	
	/**
	 * 格式化时间
	 */
	public static Date praseDate(String date,String pattern) {
		Date today = new Date();
		try {
			return new SimpleDateFormat(pattern).parse(date);
		} catch (ParseException e) {
			e.printStackTrace();
			return today;
		}
		
	}

	/**
	 * 时间校验: 不能晚于当前时间(如果晚于当前时间，则替换为当前时间)
	 */
	public static Date notAfterNow(Date myDate) {
		Date today = new Date();
		if (myDate.after(today)) {
			log.warn("myDate.after(today), set myDate = today:" + today);
			myDate = today;
		}
		return myDate;
	}

	/**
	 * 时间校验: 不能晚于昨天(如果晚于昨天，则替换为昨天)
	 */
	public static Date notAfterYesterday(Date myDate) {
		Date today = new Date();
		Date yesterday = DateUtils.addDays(today, -1);
		if (myDate.after(yesterday)) {
			myDate = yesterday;
		}
		return myDate;
	}

	/**
	 * 时间校验: 不能晚于上一个月(如果晚于上一个月，则替换为上一个月)
	 */
	public static Date notAfterLastMonth(Date myDate) {
		Date today = new Date();
		Date lastMonth = DateUtils.addMonths(today, -1);
		lastMonth = DateTools.getMaxDateOfMonth(lastMonth);
		if (myDate.after(lastMonth)) {
			myDate = lastMonth;
		}
		return myDate;
	}

	/**
	 * 时间校验: myDate不能早于basicDate(如果早于basicDate，则替换为basicDate)
	 */
	public static Date notBefore(Date myDate, String basicStr) throws Exception {
		Date basicDate = DateTools.stringToDateTime(basicStr);
		if (myDate.before(basicDate)) {
			myDate = basicDate;
		}
		return myDate;
	}

	/***
	 * 将日期转化为字符串。 字符串格式("yyyy-MM-dd HH:mm:ss")。
	 */
	public static String dateTime2String(Date date) {
		return dateToString(date, DATE_PATTERN_DEFAULT);
	}

	/***
	 * 将日期转化为字符串。 字符串格式("yyyy-MM-dd")，小时、分、秒被忽略。
	 */
	public static String dateToString(Date date) {
		return dateToString(date, DATE_PATTERN_DAY);
	}

	/***
	 * 将日期转化为字符串
	 */
	public static String dateToString(Date date, String pattern) {
		String str = "";
		try {
			if (date != null) {
				SimpleDateFormat formater = new SimpleDateFormat(pattern);
				str = formater.format(date);
			}
		} catch (Throwable e) {
			log.error(e);
		}
		return str;
	}

	/**
	 * 将字符串转化为日期
	 */
	public static Date stringToDateTime(String str) throws Exception {
		return getDateFormatOfDefault().parse(str);
	}

	/**
	 * 获取默认的DateFormat
	 */
	public static DateFormat getDateFormatOfDefault() {
		return new SimpleDateFormat(DATE_PATTERN_DEFAULT);
	}

	/**
	 * 将字符串转化为日期。 字符串格式("YYYY-MM-DD")
	 * 例如："2012-07-01"或者"2012-7-1"或者"2012-7-01"或者"2012-07-1"是等价的
	 */
	public static Date stringToDate(String str, String pattern) {
		Date dateTime = null;
		try {
			SimpleDateFormat formater = new SimpleDateFormat(pattern);
			dateTime = formater.parse(str);
		} catch (Exception e) {
			log.error(e);
		}
		return dateTime;
	}

	/**
	 * 转化成默认时间格式 yyyy-MM-dd
	 */
	public static Date strToDateDefault(String str) {
		return stringToDate(str, DATE_PATTERN_DAY);
	}

	/**
	 * 转成成时间格式 yyyy-MM-dd HH:mm:ss
	 */
	public static Date strToDateTime(String str) {
		return stringToDate(str, DATE_PATTERN_DEFAULT);
	}

	/**
	 * 将字符串转化为日期(从一种格式到另一种格式)。
	 */
	public static String strPatrToPatr(String str, String pattern1, String pattern2) {
		Date dateTime = null;
		String productStr = "";
		try {
			if (!(str == null || str.equals(""))) {
				SimpleDateFormat formater = new SimpleDateFormat(pattern1);
				dateTime = formater.parse(str);
				SimpleDateFormat formater1 = new SimpleDateFormat(pattern2);
				productStr = formater1.format(dateTime);
			}
		} catch (Exception ex) {
			log.error(ex);
		}
		return productStr;
	}

	/**
	 * 取得一个date对象对应的日期的0分0秒时刻的Date对象。
	 */
	public static Date getMinDateOfHour(Date date) {
		if (date == null) {
			return null;
		}
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.MINUTE, calendar.getActualMinimum(Calendar.MINUTE));
		calendar.set(Calendar.SECOND, calendar.getActualMinimum(Calendar.SECOND));
		calendar.set(Calendar.MILLISECOND, calendar.getActualMinimum(Calendar.MILLISECOND));
		return calendar.getTime();
	}

	/**
	 * 取得一个date对象n个小时之后的Date对象
	 */
	public static Date getTimeAfterHours(Date date, int hours) {
		if (date == null) {
			return null;
		}
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY) + hours);
		return calendar.getTime();
	}

	/**
	 * 取得一个date对象对应的日期的0点0分0秒时刻的Date对象。
	 */
	public static Date getMinDateOfDay(Date date) {
		if (date == null) {
			return null;
		}
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(getMinDateOfHour(date));
		calendar.set(Calendar.HOUR_OF_DAY, calendar.getActualMinimum(Calendar.HOUR_OF_DAY));
		return calendar.getTime();
	}

	/**
	 * 取得一月中的最早一天。
	 */
	public static Date getMinDateOfMonth(Date date) {
		if (date == null) {
			return null;
		}
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMinimum(Calendar.DAY_OF_MONTH));
		calendar.set(Calendar.HOUR_OF_DAY, calendar.getActualMinimum(Calendar.HOUR_OF_DAY));
		calendar.set(Calendar.MINUTE, calendar.getActualMinimum(Calendar.MINUTE));
		calendar.set(Calendar.SECOND, calendar.getActualMinimum(Calendar.SECOND));
		calendar.set(Calendar.MILLISECOND, calendar.getActualMinimum(Calendar.MILLISECOND));
		return calendar.getTime();
	}

	/**
	 * 取得一月中的最早一天。 date yyyy-MM
	 */
	public static String getMinDateOfMonth(String date) {
		try {
			SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_PATTERN_MONTH);
			Date minDateOfMonth = getMinDateOfMonth(dateFormat.parse(date));
			dateFormat = new SimpleDateFormat(DATE_PATTERN_DAY);
			String begin = dateFormat.format(minDateOfMonth);
//			System.out.println(begin);
			return begin;
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return date;
	}

	/**
	 * 取得一月中的最后一天
	 */
	public static Date getMaxDateOfMonth(Date date) {
		if (date == null) {
			return null;
		}
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
		calendar.set(Calendar.HOUR_OF_DAY, calendar.getActualMaximum(Calendar.HOUR_OF_DAY));
		calendar.set(Calendar.MINUTE, calendar.getActualMaximum(Calendar.MINUTE));
		calendar.set(Calendar.SECOND, calendar.getActualMaximum(Calendar.SECOND));
		calendar.set(Calendar.MILLISECOND, calendar.getActualMaximum(Calendar.MILLISECOND));
		return calendar.getTime();
	}

	/**
	 * 取得一月中的最早一天。 date yyyy-MM
	 */
	public static String getMaxDateOfMonth(String date) {
		try {
			SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_PATTERN_MONTH);
			Date minDateOfMonth = getMaxDateOfMonth(dateFormat.parse(date));
			dateFormat = new SimpleDateFormat(DATE_PATTERN_DAY);
			String end = dateFormat.format(minDateOfMonth);
//			System.out.println(end);
			return end;
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return date;
	}

	/**
	 * 取得一个date对象对应的日期的23点59分59秒时刻的Date对象。
	 */
	public static Date getMaxDateOfDay(Date date) {
		if (date == null) {
			return null;
		}
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.HOUR_OF_DAY, calendar.getActualMaximum(Calendar.HOUR_OF_DAY));
		calendar.set(Calendar.MINUTE, calendar.getActualMaximum(Calendar.MINUTE));
		calendar.set(Calendar.SECOND, calendar.getActualMaximum(Calendar.SECOND));
		calendar.set(Calendar.MILLISECOND, calendar.getActualMaximum(Calendar.MILLISECOND));
		return calendar.getTime();
	}

	/**
	 * 取得一个date对象对应的小时的59分59秒时刻的Date对象。
	 */
	public static Date getMaxDateOfHour(Date date) {
		if (date == null) {
			return null;
		}
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.MINUTE, calendar.getActualMaximum(Calendar.MINUTE));
		calendar.set(Calendar.SECOND, calendar.getActualMaximum(Calendar.SECOND));
		calendar.set(Calendar.MILLISECOND, calendar.getActualMaximum(Calendar.MILLISECOND));
		return calendar.getTime();
	}

	/**
	 * 获取2个时间相隔几秒
	 */
	public static int getBetweenSecondNumber(Date startDate, Date endDate) {
		if (startDate == null || endDate == null) {
			return -1;
		}
		if (startDate.after(endDate)) {
			Date tmp = endDate;
			endDate = startDate;
			startDate = tmp;
		}
		long timeNumber = -1L;
		long time = 1000L;
		try {
			timeNumber = (endDate.getTime() - startDate.getTime()) / time;
		} catch (Exception e) {
			log.error(e);
		}
		return (int) timeNumber;
	}

	/**
	 * 获取2个时间相隔几分钟
	 */
	public static int getBetweenMinuteNumber(Date startDate, Date endDate) {
		if (startDate == null || endDate == null) {
			return -1;
		}
		if (startDate.after(endDate)) {
			Date tmp = endDate;
			endDate = startDate;
			startDate = tmp;
		}
		long timeNumber = -1l;
		long TIME = 60L * 1000L;
		try {
			timeNumber = (endDate.getTime() - startDate.getTime()) / TIME;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return (int) timeNumber;
	}

	/**
	 * 获取2个时间相隔几小时
	 */
	public static int getBetweenHourNumber(Date startDate, Date endDate) {
		if (startDate == null || endDate == null) {
			return -1;
		}
		if (startDate.after(endDate)) {
			Date tmp = endDate;
			endDate = startDate;
			startDate = tmp;
		}
		long timeNumber = -1l;
		long time = 60L * 60L * 1000L;
		try {
			timeNumber = (endDate.getTime() - startDate.getTime()) / time;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return (int) timeNumber;
	}

	/**
	 * 获取2个时间相隔几天 "2010-08-01 00:00:00 - 2010-08-03 23:59:59"算三天
	 */
	public static int getBetweenDayNumber(Date startDate, Date endDate) {
		if (startDate == null || endDate == null) {
			return -1;
		}
		if (startDate.after(endDate)) {
			Date tmp = endDate;
			endDate = startDate;
			startDate = tmp;
		}
		long dayNumber = -1L;
		long DAY = 24L * 60L * 60L * 1000L;
		try {
			dayNumber = (endDate.getTime() + 1000 - startDate.getTime()) / DAY;
		} catch (Exception e) {
			log.error(e);
		}
		return (int) dayNumber;
	}

	/**
	 * 获取2个时间相隔几月
	 */
	public static int getBetweenMonthNumber(Date startDate, Date endDate) {
		int result = 0;
		try {
			if (startDate == null || endDate == null) {
				return -1;
			}
			if (startDate.after(endDate)) {
				Date tmp = endDate;
				endDate = startDate;
				startDate = tmp;
			}
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(startDate);
			int monthS = calendar.get(Calendar.MONTH);
			int yearS = calendar.get(Calendar.YEAR);
			calendar.setTime(endDate);
			int monthE = calendar.get(Calendar.MONTH);
			int yearE = calendar.get(Calendar.YEAR);
			if (yearE - yearS == 0) {
				result = monthE - monthS;
			} else {
				result = (yearE - yearS - 1) * 12 + (12 - monthS) + monthE;
			}
		} catch (Exception e) {
			log.error(e);
		}
		return result;
	}

	/**
	 * 返回2个日期中的大者
	 */
	public static Date max(Date date1, Date date2) {
		if (date1 == null && date2 == null) {
			return null;
		}
		if (date1 == null) {
			return date2;
		}
		if (date2 == null) {
			return date1;
		}
		if (date1.after(date2)) {
			return date1;
		} else {
			return date2;
		}
	}

	/**
	 * 返回不大于date2的日期 如果 date1 >= date2 返回date2 如果 date1 < date2 返回date1
	 */
	public static Date ceil(Date date1, Date date2) {
		if (date1 == null && date2 == null) {
			return null;
		}
		if (date1 == null) {
			return date2;
		}
		if (date2 == null) {
			return date1;
		}
		if (date1.after(date2)) {
			return date2;
		} else {
			return date1;
		}
	}

	/**
	 * 返回不小于date2的日期 如果 date1 >= date2 返回date1 如果 date1 < date2 返回date2
	 */
	public static Date floor(Date date1, Date date2) {
		if (date1 == null && date2 == null) {
			return null;
		}
		if (date1 == null) {
			return date2;
		}
		if (date2 == null) {
			return date1;
		}
		if (date1.after(date2)) {
			return date1;
		} else {
			return date2;
		}
	}

	/**
	 * 返回2个日期中的小者
	 */
	public static Date min(Date date1, Date date2) {
		if (date1 == null && date2 == null) {
			return null;
		}
		if (date1 == null) {
			return date2;
		}
		if (date2 == null) {
			return date1;
		}
		if (date1.after(date2)) {
			return date2;
		} else {
			return date1;
		}
	}

	/**
	 * 输入日期是否为同一天.
	 */
	public static boolean isTheSameDay(Date startDate, Date endDate) {
		String startDateStr = dateToString(startDate);
		String endDateStr = dateToString(endDate);
		return startDateStr.equals(endDateStr);
	}

	/**
	 * 根据时间,返回Calendar
	 */
	public static Calendar getCalendar(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		return cal;
	}

	/**
	 * 根据字符串时间,返回Calendar
	 */
	public static Calendar getCalendar(String dateStr) {
		Calendar cal = Calendar.getInstance();
		if (StringUtils.isNotBlank(dateStr)) {
			Date date = DateTools.stringToDate(dateStr, DATE_PATTERN_DEFAULT);
			cal.setTime(date);
		}
		return cal;
	}

	/**
	 * 获传入时间date的年份
	 */
	public static int getYear(Date date) {
		Calendar cal = getCalendar(date);
		return cal.get(Calendar.YEAR);
	}

	/**
	 * 获传入时间date的月份
	 */
	public static int getMonth(Date date) {
		Calendar cal = getCalendar(date);
		return (cal.get(Calendar.MONDAY) + 1);
	}

	/**
	 * 获传入时间date的天
	 */
	public static int getDay(Date date) {
		Calendar cal = getCalendar(date);
		return cal.get(Calendar.DAY_OF_MONTH);
	}

	/**
	 * 获传入时间date的小时
	 */
	public static int getHour(Date date) {
		Calendar cal = getCalendar(date);
		return cal.get(Calendar.HOUR_OF_DAY);
	}

	/**
	 * 获传入时间date的分钟
	 */
	public static int getMinute(Date date) {
		Calendar cal = getCalendar(date);
		return cal.get(Calendar.MINUTE);
	}

	/**
	 * 获传入时间date的秒
	 */
	public static int getSecond(Date date) {
		Calendar cal = getCalendar(date);
		return cal.get(Calendar.SECOND);
	}
	/** 
     * 获取当前日期是星期几
     *  
     */  
	public static int getWeekOfDate(Date dt) {
		int[] weekDays = { 7, 1, 2, 3, 4, 5, 6 };
		Calendar cal = getCalendar(dt);
		int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
		if (w < 0)
			w = 0;
		return weekDays[w];
	}

	/**
	 * 给定一个日期和天数，得到这个日期+天数的日期
	 */
	public static String getNextDay(String date, int num) {
		Date d = stringToDate(date, DATE_PATTERN_DAY);
		Calendar ca = Calendar.getInstance();
		ca.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
		ca.setTime(d);
		int day = ca.get(Calendar.DATE);
		day = day + num;
		ca.set(Calendar.DATE, day);
		return getFormatDateTime(ca.getTime(), DATE_PATTERN_DAY);
	}

	/**
	 * 给定一个日期和天数，得到这个日期+天数的日期对应的0时0分0秒
	 * 
	 * @throws Exception
	 */
	public static Date getNextDay(Date date, int num) {
		Calendar ca = Calendar.getInstance();
		ca.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
		ca.setTime(date);
		int day = ca.get(Calendar.DATE);
		day = day + num;
		ca.set(Calendar.DATE, day);
		return getMinDateOfDay(ca.getTime());
	}

	/**
	 * 根据指定格式获取日期数据
	 */
	private static String getFormatDateTime(Date date, String pattern) {
		if (null == date) {
			return "";
		}
		SimpleDateFormat format = new SimpleDateFormat(pattern);
		format.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
		return format.format(date);
	}

	/**
	 * 获取给定日期的下一个月的日期的最晚时间
	 */
	public static Date getNextMonthDay(Date startDate) {
		Date monthEndDate = getMaxDateOfMonth(startDate);
		Date nextMonth = DateUtils.addMonths(startDate, 1);
		nextMonth = stringToDate(dateToString(nextMonth, DATE_PATTERN_DAY) + DAY_LAST_TIME, DATE_PATTERN_DEFAULT);
		if (isTheSameDay(startDate, monthEndDate)) {
			nextMonth = getMaxDateOfMonth(nextMonth);
		}
		return nextMonth;
	}

	/**
	 * 获取给定日期的下几个月的日期的最晚时间
	 */
	public static Date getNextManyMonthDay(Date startDate, int month) {
		Date monthEndDate = getMaxDateOfMonth(startDate);
		Date nextMonth = DateUtils.addMonths(startDate, month);
		nextMonth = stringToDate(dateToString(nextMonth, DATE_PATTERN_DAY) + DAY_LAST_TIME, DATE_PATTERN_DEFAULT);
		if (isTheSameDay(startDate, monthEndDate)) {
			nextMonth = getMaxDateOfMonth(nextMonth);
		}
		return nextMonth;
	}

	/**
	 * 获取几秒后/前的时间
	 */
	public static Date getNewDate(Date date, int seconds) {
		long millSeconds = date.getTime();
		millSeconds += seconds * 1000;
		return new Date(millSeconds);
	}

	/**
	 * 给定一个日期和秒，得到这个日期 + 秒的日期
	 */
	public static String getNextSecond(Date date, int seconds) {
		Calendar ca = Calendar.getInstance();
		ca.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
		ca.setTime(date);
		int second = ca.get(Calendar.SECOND);
		second = second + seconds;
		ca.set(Calendar.SECOND, second);
		return getFormatDateTime(ca.getTime(), DATE_PATTERN_DEFAULT);

	}

	/**
	 * 给定一个时间和天数，得到这个时间+小时的日期
	 */
	public static String getNextHour(Date date, int num) {
		Calendar ca = Calendar.getInstance();
		ca.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
		ca.setTime(date);
		int day = ca.get(Calendar.HOUR);
		day = day + num;
		ca.set(Calendar.HOUR, day);
		return getFormatDateTime(ca.getTime(), DATE_PATTERN_DEFAULT);
	}

	/**
	 * 给定一个时间和天数，得到这个时间+分钟的日期
	 */
	public static String getNextMinute(Date date, int num) {
		Calendar ca = Calendar.getInstance();
		ca.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
		ca.setTime(date);
		int day = ca.get(Calendar.MINUTE);
		day = day + num;
		ca.set(Calendar.MINUTE, day);
		return getFormatDateTime(ca.getTime(), DATE_PATTERN_DEFAULT);
	}

	/**
	 * 给定一个时间和天数，得到这个时间+天数的日期
	 */
	public static String getNextNewDay(Date date, int num) {
		Calendar ca = Calendar.getInstance();
		ca.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
		ca.setTime(date);
		int day = ca.get(Calendar.DATE);
		day = day + num;
		ca.set(Calendar.DATE, day);
		return getFormatDateTime(ca.getTime(), DATE_PATTERN_DEFAULT);
	}

	/**
	 * 给定一个时间和天数，得到这个时间+天数的日期
	 */
	public static String getNextDaytime(String date, int num) {
		Date d = stringToDate(date, DATE_PATTERN_DEFAULT);
		Calendar ca = Calendar.getInstance();
		ca.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
		ca.setTime(d);
		int day = ca.get(Calendar.DATE);
		day = day + num;
		ca.set(Calendar.DATE, day);
		return getFormatDateTime(ca.getTime(), DATE_PATTERN_DEFAULT);
	}

	/**
	 * 给定一个时间和天数，得到这个时间+天数的日期
	 */
	public static String getNextNewDate(Date date, int num) {
		Calendar ca = Calendar.getInstance();
		ca.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
		ca.setTime(date);
		int day = ca.get(Calendar.DATE);
		day = day + num;
		ca.set(Calendar.DATE, day);
		return getFormatDateTime(ca.getTime(), DATE_PATTERN_DEFAULT);
	}

	/**
	 * 传入时间date加天数num，返回字符串格式：yyyy-MM-dd
	 */
	public static String getAddDaytime(String date, int num) {
		Date d = stringToDate(date, DATE_PATTERN_DAY);
		Calendar ca = Calendar.getInstance();
		ca.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
		ca.setTime(d);
		int day = ca.get(Calendar.DATE);
		day = day + num;
		ca.set(Calendar.DATE, day);
		return getFormatDateTime(ca.getTime(), DATE_PATTERN_DAY);
	}

	/**
	 * 当前时间减天数num,返回字符串格式：yyyy-MM-dd
	 */
	public static String getFrontDaytime(int num) {
		Calendar ca = Calendar.getInstance();
		ca.add(Calendar.DATE, -num);
		return getFormatDateTime(ca.getTime(), DATE_PATTERN_DAY);
	}

	/**
	 * 当前时间减天数num,返回Date类型
	 */
	public static Date getFrontDay(int num) {
		Calendar ca = Calendar.getInstance();
		ca.add(Calendar.DATE, -num);
		return ca.getTime();
	}

	/**
	 * 获取系统时间格式：yyyy-MM-dd
	 */
	public static String getNowDate() {
		return getNowtime(DATE_PATTERN_DAY);
	}

	/**
	 * 获取系统时间格式：yyyy-MM-dd HH:mm:ss
	 */
	public static String getNowtime() {
		return getNowtime(DATE_PATTERN_DEFAULT);
	}

	/**
	 * 根据传入格式获取系统时间
	 */
	public static String getNowtime(String formatter) {
		Calendar ca = Calendar.getInstance();
		return getFormatDateTime(ca.getTime(), formatter);
	}

	/**
	 * 当前时间减月份num
	 */
	public static String getFrontMonthtime(int num) {
		Calendar ca = Calendar.getInstance();
		ca.add(Calendar.MONTH, -num);
		return getFormatDateTime(ca.getTime(), DATE_PATTERN_DAY);
	}

	/**
	 * 根据传入时间减月份num
	 */
	public static String getMonthtime(Date date, int num) {
		Calendar ca = Calendar.getInstance();
		ca.setTime(date);
		ca.add(Calendar.MONTH, -num);
		return getFormatDateTime(ca.getTime(), DATE_PATTERN_DAY);
	}

	/**
	 * 根据传入时间格式获取系统时间
	 */
	public static String getSysTime(String formatter) {
		Calendar c = Calendar.getInstance();
		SimpleDateFormat fmt = new SimpleDateFormat(formatter);
		return fmt.format(c.getTime());
	}

	/**
	 * 传入时间date加月份num
	 */
	public static String getFrontMonthDate(String date, int num) {
		SimpleDateFormat formater = new SimpleDateFormat(DATE_PATTERN_DAY);
		try {
			Date dateTime = formater.parse(date);
			Calendar c = Calendar.getInstance();
			c.setTime(dateTime);
			c.add(Calendar.MONTH, num);
			return formater.format(c.getTime());
		} catch (Exception e) {
			return "";
		}
	}

	/**
	 * 当前yyyy-MM-dd + 传入时间HH:mm:ss, 返回时间long类型
	 */
	public static long getMicTimes(String time) {
		SimpleDateFormat fmat = new SimpleDateFormat(DATE_PATTERN_DEFAULT);
		Date dateTime = null;
		try {
			dateTime = fmat.parse(dateToString(new Date()) + " " + time);
		} catch (Exception e) {
			log.error(e);
		}
		return dateTime.getTime();
	}

	/**
	 * 当前的HH:mm:ss这个时间和当前时间相隔多少毫秒
	 */
	public static int getTimeDist(String time) {
		int distTime = 0;
		try {
			SimpleDateFormat fmat = new SimpleDateFormat(DATE_PATTERN_DEFAULT);
			Date dateTime = fmat.parse(dateToString(new Date()) + " " + time);
			distTime = (int) (dateTime.getTime() - new Date().getTime());
		} catch (Exception e) {
			log.error(e);
		}
		return distTime;
	}

	/**
	 * 传入时间date在timeSize分钟后是否过期
	 */
	public static boolean isPastdue(String date, int timeSize) throws Exception {
		long now = System.currentTimeMillis();
		long time = stringToDateTime(date).getTime();
		return (now - time) > (timeSize * HOUR_TO_MILLISECOND);
	}

	/**
	 * 比较当前时间和传入时间加上年数的大小， 传入时间compareDate大 返回true,否则返回false
	 */
	public static boolean isNowOrDateGt(Date compareDate, Date needDate, int addYear) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(compareDate);
		cal.add(Calendar.YEAR, addYear);
		compareDate = cal.getTime();
		int i = compareDate.compareTo(needDate);
		return i >= 0;
	}

	/**
	 * 获取当前时间第二天的yyyy-MM-dd + 传入时间的HH:mm:ss
	 */
	public static Date getTomorrowTime(int hour, int minute, int seconds) {
		Date today = new Date();
		Date tomorrow = DateUtils.addDays(today, 1);
		Date tomorrowSetMinute = DateUtils.setMinutes(tomorrow, minute);
		Date tomorrowSetSeconds = DateUtils.setSeconds(tomorrowSetMinute, seconds);
		return DateUtils.setHours(tomorrowSetSeconds, hour);
	}

	/**
	 * 获取当前时间yyyy-MM-dd + 传入时间的HH:mm:ss
	 */
	public static Date getTodayTime(int hour, int minute, int seconds) {
		Date today = new Date();
		Date todayMinute = DateUtils.setMinutes(today, minute);
		Date todaySeconds = DateUtils.setSeconds(todayMinute, seconds);
		return DateUtils.setHours(todaySeconds, hour);
	}

	/**
	 * 获取当前时间yyyy-MM-dd + 传入时间的HH:mm:ss
	 */
	public static Date getTodayTime(Date date) {
		Calendar cal = getCalendar(date);
		int hour = cal.get(Calendar.HOUR_OF_DAY);
		int minute = cal.get(Calendar.MINUTE);
		int second = cal.get(Calendar.SECOND);
		return getTodayTime(hour, minute, second);
	}

	/**
	 * 比较当前时间和传入date
	 */
	public static boolean isGt(String date) {
		try {
			Date endDate = stringToDateTime(date);
			Date nowDate = new Date();
			if (endDate.compareTo(nowDate) == 1) {
				return true;
			}
		} catch (Exception e) {
		}
		return false;
	}

	/**
	 * 日期之前
	 */
	public static boolean isBefore(Date date, Date date2) {
		return null != date && null != date2 && date.before(date2);
	}

	/**
	 * 日期之后
	 */
	public static boolean isAfter(Date date, Date date2) {
		return null != date && null != date2 && date.after(date2);
	}

	/**
	 * 时间之中如：09:00:00到10:08:00时间之前返回true
	 */
	public static boolean isBetween(String sDate, String eDate) {
		Date stDate = stringToDate(sDate, DATE_PATTERN_TIME);
		Date enDate = stringToDate(eDate, DATE_PATTERN_TIME);
		Date sysDate = stringToDate(getNowtime(DATE_PATTERN_TIME), DATE_PATTERN_TIME);
		return isAfter(sysDate, stDate) && isBefore(sysDate, enDate);
	}

	/**
	 * 时间之中如：09:00:00到10:08:00时间之前返回true
	 */
	public static boolean isBetween(Date date, String sDate, String eDate) {
		Date stDate = stringToDate(sDate, DATE_PATTERN_TIME);
		Date enDate = stringToDate(eDate, DATE_PATTERN_TIME);
		Date datetime = stringToDate(dateToString(date, DateTools.DATE_PATTERN_TIME), DATE_PATTERN_TIME);
		return isAfter(datetime, stDate) && isBefore(datetime, enDate);
	}

	/**
	 * 日期之中
	 */
	public static boolean isBetween(Date date, Date date2, Date date3) {
		return null != date && isAfter(date, date2) && isBefore(date, date3);
	}

	/**
	 * 日期之中(前闭后开：data2<=data<data3)
	 */
	public static boolean isBetweenEqualsBefore(Date date, Date date2, Date date3) {
		return null != date && isBefore(date, date3) && !isBefore(date, date2);
	}

	/**
	 * 某一个日期n月相对应某一天 n 为负值表示向前 n 为正值表示向后
	 */
	public static Date calDateForMonth(Date date, int n) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.add(Calendar.MONTH, n);
		return c.getTime();
	}

	/**
	 * 某一个日期n天相对应某一天 n 为负值表示向前 n 为正值表示向后
	 */
	public static Date calDateForDay(Date date, int n) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.add(Calendar.DAY_OF_MONTH, n);
		return c.getTime();
	}

	/**
	 * 某一个日期n天相对应某一天 n 为负值表示向前 n 为正值表示向后
	 */
	public static Date calDateForYear(Date date, int n) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.add(Calendar.YEAR, n);
		return c.getTime();
	}

	/**
	 * 取某一个时间相对某一时间n小时向前或向后的时间
	 */
	public static Date calDateForHour(Date date, int n) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.add(java.util.Calendar.HOUR_OF_DAY, n);
		return c.getTime();
	}

	/**
	 * 取某一时间相对某一时间n分钟向前或向后的时间
	 */
	public static Date calDateForMin(Date date, int n) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.add(java.util.Calendar.MINUTE, n);
		return c.getTime();
	}

	/**
	 * 两个日期之间的天的计算
	 * 
	 * @param startDate
	 * @param endDate
	 * @return
	 */
	public static int getBetweenDay(Date startDate, Date endDate) {
		if (startDate == null || endDate == null) {
			return -1;
		}
		if (startDate.after(endDate)) {
			Date tmp = endDate;
			endDate = startDate;
			startDate = tmp;
		}
		long dayNumber = -1L;
		long DAY = 24L * 60L * 60L * 1000L;
		Calendar tempCal = Calendar.getInstance();
		Calendar startCal = Calendar.getInstance();
		tempCal.setTime(startDate);
		startCal.set(tempCal.get(Calendar.YEAR), tempCal.get(Calendar.MONTH), tempCal.get(Calendar.DATE), 0, 0, 0);

		Calendar endCal = Calendar.getInstance();
		tempCal.setTime(endDate);
		endCal.set(tempCal.get(Calendar.YEAR), tempCal.get(Calendar.MONTH), tempCal.get(Calendar.DATE), 0, 0, 0);
		try {
			dayNumber = (endCal.getTime().getTime() - startCal.getTime().getTime()) / DAY;
		} catch (Exception e) {
			log.error(e);
		}
		return (int) dayNumber;
	}

	/**
	 * 根据日期获取生肖
	 * 
	 * @return
	 */
	public static String getZodica(Date date) {
		if (null != date && !"".equals(date.toString())) {
			Calendar cal = Calendar.getInstance();
			cal.setTime(date);
			int year = cal.get(Calendar.YEAR);
			return year == 0 ? "" : ZODIAC_ARR[year % 12];
		}
		return "";
	}

	/**
	 * 根据日期获取星座
	 * 
	 * @return
	 */
	public static String getConstellation(Date date) {
		if (null != date && !"".equals(date.toString())) {
			Calendar cal = Calendar.getInstance();
			cal.setTime(date);
			int month = cal.get(Calendar.MONTH);
			int day = cal.get(Calendar.DAY_OF_MONTH);
			if (day < CONSTELLATION_EDGE_DAY[month]) {
				month -= 1;
			}
			if (month >= 0) {
				return CONSTELLATION_ARR[month];
			}
		}
		return CONSTELLATION_ARR[11];
	}

	/**
	 * 根据星座获取生日范围
	 */
	public static Map<String, Integer> getBirthdaysByConstellation(String constellation) {
		Map<String, Integer> date = new HashMap<>();
		int startM, startD, endM, endD;// 起始月
		for (int i = 0; i < 12; i++) {
			if (CONSTELLATION_ARR[i].equals(constellation)) {
				startM = (i + 1);
				startD = (CONSTELLATION_EDGE_DAY[i]);
				if (i == 11) {
					endM = 12;
					endD = 31;
				} else {
					endM = i + 2;
					endD = CONSTELLATION_EDGE_DAY[i + 1] - 1;
				}
				date.put("startM", startM);
				date.put("startD", startD);
				date.put("endM", endM);
				date.put("endD", endD);
				break;
			}
		}
		return date;
	}

	/**
	 * specifiedDay - day date
	 * 
	 * @param specifiedDay
	 * @param beftDay
	 * @return
	 */
	public static Date getSpecifiedDayBefore(Date specifiedDay, Integer beforeDay) {
		Calendar c = Calendar.getInstance();
		c.setTime(specifiedDay);
		int day = c.get(Calendar.DATE);
		c.set(Calendar.DATE, day - beforeDay);

		String dayBefore = new SimpleDateFormat(DATE_PATTERN_DEFAULT).format(c.getTime());
		Date date = null;
		try {
			date = new SimpleDateFormat(DATE_PATTERN_DEFAULT).parse(dayBefore);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return date;
	}

	/**
	 * 是否是闰年
	 * 
	 * @return
	 */
	public static boolean isLeapYear(Date date) {
		int year = getYear(date);
		return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
	}

	/**
	 * 获取传入时间的加减num年份的时间
	 * 
	 * @param num
	 * @param date
	 * @return
	 */
	public static Date getNextNumYearDate(Date date, int num) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.YEAR, num);
		return calendar.getTime();
	}

	public static void main(String[] args) {
		System.out.println(getNextNewDate(new Date(), 2));
	}

	/**
	 * 给定一个日期和秒，得到这个日期+秒的日期(Date类型)
	 *
	 * @param date
	 *            指定日期
	 * @param day
	 *            天数
	 * @return Date
	 */
	public static Date getNextSecond2(Date date, int seconds) {
		Calendar ca = Calendar.getInstance();
		ca.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
		ca.setTime(date);
		int second = ca.get(Calendar.SECOND);
		second = second + seconds;
		ca.set(Calendar.SECOND, second);
		return ca.getTime();
	}

	/**
	 * 获取2个时间相隔几天 只比较日期
	 */
	public static int getBetweenDayNum(Date startDate, Date endDate) {
		if (startDate == null || endDate == null) {
			return -1;
		}
		startDate = getMinDateOfDay(startDate);
		endDate = getMinDateOfDay(endDate);
		if (startDate.after(endDate)) {
			Date tmp = endDate;
			endDate = startDate;
			startDate = tmp;
		}
		long dayNumber = -1L;
		long DAY = 24L * 60L * 60L * 1000L;
		try {
			dayNumber = (endDate.getTime() + 1000 - startDate.getTime()) / DAY;
		} catch (Exception e) {
			log.error(e);
		}
		return (int) dayNumber;
	}

	/**
	 * 将日期转换为日历
	 * 
	 * @param date
	 *            日期
	 * @return 日历
	 */
	private static Calendar convert(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar;
	}

	/**
	 * 返回当月最后一天的日期
	 */
	public static String getLastDayOfMonth(Date date) {
		Calendar calendar = convert(date);
		calendar.set(Calendar.DATE, calendar.getMaximum(Calendar.DATE));
		return new SimpleDateFormat(DATE_PATTERN_DAY).format(calendar.getTime());
	}

	/**
	 * 获取上N个月的
	 * 
	 * @param i
	 * @return
	 */
	public static Date getBeforeXmonthTime(int n) {
		Date now = new Date();
		Calendar calendar = Calendar.getInstance();// 日历对象
		calendar.setTime(now);// 设置当前日期
		calendar.add(Calendar.MONTH, -n);
		return calendar.getTime();
	}

	/**
	 * 获取00:00:00时间
	 * 
	 * @param i
	 * @return
	 */
	public static Date get0Oclock(String date) {
		try {
			SimpleDateFormat dateFormat = new SimpleDateFormat(DateTools.DATE_PATTERN_DEFAULT);
			String oclock = date + " 00:00:00";
			return dateFormat.parse(oclock);
		} catch (ParseException e) {

		}
		return null;
	}

	/**
	 * 获取23:59:59时间
	 * 
	 * @param i
	 * @return
	 */
	public static Date get23Oclock(String date) {
		try {
			SimpleDateFormat dateFormat = new SimpleDateFormat(DateTools.DATE_PATTERN_DEFAULT);
			String oclock = date + " 23:59:59";
			return dateFormat.parse(oclock);
		} catch (ParseException e) {

		}
		return null;
	}

	/**
	 * @param dateOfBirth
	 * @return
	 */
	public static int getAgeByBirth(String birthdayStr) {
        try {
			int age = 0;
			Calendar born = Calendar.getInstance();
			Calendar now = Calendar.getInstance();
			SimpleDateFormat format = new SimpleDateFormat(DATE_PATTERN_DAY);
			Date dateOfBirth = format.parse(birthdayStr);
			if (dateOfBirth != null) {
			    now.setTime(new Date());
			    born.setTime(dateOfBirth);
			    if (born.after(now)) {
			        throw new IllegalArgumentException("年龄不能超过当前日期");
			    }
			    age = now.get(Calendar.YEAR) - born.get(Calendar.YEAR);
			    int nowDayOfYear = now.get(Calendar.DAY_OF_YEAR);
			    int bornDayOfYear = born.get(Calendar.DAY_OF_YEAR);
			    if (nowDayOfYear < bornDayOfYear) {
			        age -= 1;
			    }
			}
			return age;
		} catch (ParseException e) {
			return 0;
		}
    }
	
	/**
	 * 把long类型日期转化为格式化字符串日期
	 * @param longTimeStamp long类型时间戳
	 * @param pattern   格式
	 * @return  String(格式化后的日期)
	 */
	public static String longTimeStampToStringDate(Long longTimeStamp, String pattern) {
		if (longTimeStamp == null || StringUtils.isBlank(pattern)) {
			throw new NullPointerException("时间戳或格式类型不能为空");
		}
		Date date = new Date(longTimeStamp);
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
		String formatDate = simpleDateFormat.format(date);
		return formatDate;
	}

	/**
	 * 把字符串日期转换为LonG类型日期
	 * @param time 字符串日期
	 * @param pattern 格式
	 * @return Long日期
	 * @throws ParseException
	 */
	public static Long stringTimeToLongTimeStamp(String time,String pattern) throws ParseException {
		if(StringUtils.isBlank(time) || StringUtils.isBlank(pattern)) {
			throw new NullPointerException("时间或格式类型不能为空");
		}
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
		Long formateDate = simpleDateFormat.parse(time).getTime();
		return formateDate;
	}
}